from flask import Flask, url_for, render_template, redirect, request, flash, jsonify
from markupsafe import escape
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate, upgrade
import secrets
from flask_login import (
    login_user, UserMixin, login_required, current_user,
    logout_user, LoginManager
)
import click
from datetime import datetime
import markdown
import requests
from bs4 import BeautifulSoup
import random
import smtplib
from email.mime.text import MIMEText
from email.header import Header
from openai import OpenAI
from tenacity import retry, stop_after_attempt, wait_exponential

app = Flask(__name__)
app.config['SECRET_KEY'] = secrets.token_hex(16)

# 在 PythonAnywhere 或其它环境中改成对应的地址
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:123456@localhost/test_db'
# app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://songaoxiang:770804sax@songaoxiang.mysql.pythonanywhere-services.com:3306/songaoxiang$movies'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

# 给 SQLAlchemy 设置连接池参数，防止空闲连接失效后出错
app.config['SQLALCHEMY_ENGINE_OPTIONS'] = {
    'pool_pre_ping': True,   # 每次获取连接前先 ping，若连接已断开则重连
    'pool_recycle': 280      # 280 秒后回收连接，避免超时
}

db = SQLAlchemy(app)
migrate = Migrate(app, db)

# ------------------ 模型定义 ------------------
class Movie(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(100), nullable=False)
    year = db.Column(db.String(4), nullable=False)
    description = db.Column(db.Text, nullable=True, default='')
    poster_url = db.Column(db.String(255), nullable=True)
    play_url = db.Column(db.String(255), nullable=True)  # 添加播放链接
    rating = db.Column(db.Float, nullable=True)
    director = db.Column(db.String(100), nullable=True)
    actors = db.Column(db.String(255), nullable=True)
    category = db.Column(db.String(50), nullable=True)
    reviews = db.relationship('MovieReview', backref='movie', lazy=True)
    recommend_index = db.Column(db.Integer, default=0)  # 推荐指数
    created_at = db.Column(db.DateTime, default=datetime.utcnow)

class User(db.Model, UserMixin):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(20))
    username = db.Column(db.String(20), unique=True, nullable=False)
    password = db.Column(db.String(128), nullable=False)
    email = db.Column(db.String(120), unique=True, nullable=False)
    posts = db.relationship('Post', backref='author', lazy=True)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)

    def set_password(self, password):
        # 直接将明文密码保存进数据库，不进行加密/哈希
        self.password = password

    def validate_password(self, password):
        # 直接比较明文
        return self.password == password

class Post(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(200), nullable=False)
    content = db.Column(db.Text, nullable=False)
    content_html = db.Column(db.Text)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
    category = db.Column(db.String(50))  # 分类：'tech', 'movie', 'music' 等

    def on_changed_content(self):
        self.content_html = markdown.markdown(self.content, extensions=[
            'markdown.extensions.extra',
            'markdown.extensions.codehilite',
            'markdown.extensions.toc',
        ])

# 添加电影评论模型
class MovieReview(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    content = db.Column(db.Text, nullable=False)
    rating = db.Column(db.Integer, nullable=False)  # 1-5星评分
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
    movie_id = db.Column(db.Integer, db.ForeignKey('movie.id'), nullable=False)

# 添加验证码模型
class EmailVerificationCode(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    email = db.Column(db.String(120), nullable=False)
    code = db.Column(db.String(6), nullable=False)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    is_used = db.Column(db.Boolean, default=False)

class Music(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(100), nullable=False)
    artist = db.Column(db.String(100))
    album = db.Column(db.String(100))
    year = db.Column(db.String(4))
    genre = db.Column(db.String(50))
    url = db.Column(db.String(255))  # 音乐文件URL
    cover_url = db.Column(db.String(255))  # 专辑封面URL
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
    
# 添加评论模型
class Comment(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    content = db.Column(db.Text, nullable=False)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
    post_id = db.Column(db.Integer, db.ForeignKey('post.id'), nullable=True)
    movie_id = db.Column(db.Integer, db.ForeignKey('movie.id'), nullable=True)
    music_id = db.Column(db.Integer, db.ForeignKey('music.id'), nullable=True)
    parent_id = db.Column(db.Integer, db.ForeignKey('comment.id'), nullable=True)
    replies = db.relationship('Comment', backref=db.backref('parent', remote_side=[id]))
    # 添加用户关联
    user = db.relationship('User', backref='comments')
    
    def to_dict(self):
        return {
            'id': self.id,
            'content': self.content,
            'created_at': self.created_at.strftime('%Y-%m-%d %H:%M:%S'),
            'user': {
                'id': self.user.id,
                'name': self.user.name
            },
            'replies': [reply.to_dict() for reply in self.replies]
        }

# 修改数据库初始化部分
def init_db():
    """初始化数据库"""
    with app.app_context():
        # 创建所有表
        db.create_all()
        
        # 检查是否需要添加测试数据
        if not User.query.first():
            # 创建管理员用户
            admin = User(
                username='admin',
                name='Admin',
                email='admin@example.com'
            )
            admin.set_password('123456')
            db.session.add(admin)
            
            # 添加一些测试电影数据
            movies = [
                {'title': 'My Neighbor Totoro', 'year': '1988'},
                {'title': 'Dead Poets Society', 'year': '1989'},
                {'title': 'A Perfect World', 'year': '1993'},
                {'title': 'Leon', 'year': '1994'},
                {'title': 'Mahjong', 'year': '1996'},
            ]
            for m in movies:
                movie = Movie(title=m['title'], year=m['year'])
                db.session.add(movie)
            
            db.session.commit()

# ------------------ 视图函数 ------------------
@app.route('/')
def index():
    movies = Movie.query.order_by(Movie.id.desc()).all()
    recent_posts = Post.query.order_by(Post.created_at.desc()).limit(5).all()
    return render_template('index.html', movies=movies, recent_posts=recent_posts)

@app.route('/user/<name>')
def user_page(name):
    return f"User :{escape(name)}'s website"

@app.route('/test')
def test_url_for():
    print(url_for('index'))                      # /
    print(url_for('user_page', name='greyli'))   # /user/greyli
    print(url_for('test_url_for', num=2))        # /test?num=2
    return 'Test page'

# ------------------ 全局 context_processor ------------------
from flask_login import current_user

@app.context_processor
def inject_user():
    """
    在模板里注入 user 和 current_user 变量。
    """
    try:
        user = User.query.first()  # 获取第一个用户
    except Exception:
        db.session.rollback()
        user = None
    return dict(user=user, current_user=current_user)


# ------------------ 错误处理 ------------------
@app.errorhandler(404)
def page_not_found(e):
    db.session.rollback()
    return render_template('404.html'), 404

@app.errorhandler(500)
def internal_server_error(e):
    db.session.rollback()
    return render_template('500.html'), 500

@app.errorhandler(400)
def bad_request(e):
    db.session.rollback()
    return render_template('400.html'), 400

# ------------------ 登录管理 ------------------
login_manager = LoginManager(app)
login_manager.login_view = 'login'

@login_manager.user_loader
def load_user(user_id):
    return User.query.get(int(user_id))

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']

        if not username or not password:
            flash('Invalid input.')
            return redirect(url_for('login'))

        # 调试输出：查看输入的用户名
        print(f"Looking for user with username: {username}")
        user = User.query.filter_by(username=username).first()
        if user:
            print(f"Found user: {user.username}")

        # 直接比较明文密码
        if user and user.validate_password(password):
            login_user(user)
            flash('Login success.')

            # 登录后可跳回来源页，否则默认到首页
            next_page = request.args.get('next')
            if not next_page or next_page.startswith('/logout'):
                next_page = url_for('index')
            return redirect(next_page)

        flash('Invalid username or password.')
        return redirect(url_for('login'))

    return render_template('login.html')

@app.route('/logout')
@login_required
def logout():
    logout_user()
    flash('Goodbye.')
    return redirect(url_for('index'))

# ------------------ 一些增删改操作示例 ------------------
@app.route('/movie/edit/<int:movie_id>', methods=['GET', 'POST'])
@login_required
def edit(movie_id):
    movie = Movie.query.get_or_404(movie_id)

    if request.method == 'POST':
        title = request.form['title']
        year = request.form['year']

        if not title or not year or len(year) != 4 or len(title) > 60:
            flash('Invalid input.')
            return redirect(url_for('edit', movie_id=movie_id))

        movie.title = title
        movie.year = year
        db.session.commit()
        flash('Item updated.')
        return redirect(url_for('index'))

    return render_template('edit.html', movie=movie)

@app.route('/movie/delete/<int:movie_id>', methods=['POST'])
@login_required
def delete(movie_id):
    movie = Movie.query.get_or_404(movie_id)
    db.session.delete(movie)
    db.session.commit()
    flash('Item deleted.')
    return redirect(url_for('index'))

@app.route('/settings', methods=['GET', 'POST'])
@login_required
def settings():
    if request.method == 'POST':
        name = request.form['name']

        if not name or len(name) > 20:
            flash('Invalid input.')
            return redirect(url_for('settings'))

        current_user.name = name
        db.session.commit()
        flash('Settings updated.')
        return redirect(url_for('index'))

    return render_template('settings.html')

# ------------------ 自定义命令：生成测试数据/管理员账号 ------------------
@app.cli.command()
def forge():
    """Generate fake data."""
    db.create_all()
    name = 'Grey Li'
    movies_data = [
        {'title': 'My Neighbor Totoro', 'year': '1988'},
        {'title': 'Dead Poets Society', 'year': '1989'},
        {'title': 'A Perfect World', 'year': '1993'},
        {'title': 'Leon', 'year': '1994'},
        {'title': 'Mahjong', 'year': '1996'},
        {'title': 'Swallowtail Butterfly', 'year': '1996'},
        {'title': 'King of Comedy', 'year': '1999'},
        {'title': 'Devils on the Doorstep', 'year': '1999'},
        {'title': 'WALL-E', 'year': '2008'},
        {'title': 'The Pork of Music', 'year': '2012'},
    ]
    user = User(name=name, username='admin', password='123456')  # 默认直接设置明文密码
    db.session.add(user)
    for m in movies_data:
        movie = Movie(title=m['title'], year=m['year'])
        db.session.add(movie)
    db.session.commit()
    click.echo('Done.')

@app.cli.command()
@click.option('--username', prompt=True, help='The username used to login.')
@click.option('--password', prompt=True, hide_input=True, confirmation_prompt=True, help='The password used to login.')
def admin(username, password):
    """
    创建/更新用户: 不用哈希, 直接存明文密码.
    请记住, 这在生产环境下是不安全的!
    """
    db.create_all()
    user = User.query.first()
    if user is not None:
        click.echo('Updating user...')
        user.username = username
        user.set_password(password)  # 直接保存明文
    else:
        click.echo('Creating user...')
        user = User(username=username, name='Admin', password=password)
        db.session.add(user)

    db.session.commit()
    click.echo('Done.')

# 添加邮件配置
EMAIL_CONFIG = {
    'mail_host': "smtp.qq.com",  # SMTP服务器地址
    'port': 465,  # SMTP服务器端口
    'send_by': "3529935252@qq.com",  # 发件人邮箱
    'mail_pass': "wqoruyrulwkzcjdh"  # QQ邮箱授权码
}

def send_verification_email(to_email, code):
    """发送验证码邮件"""
    try:
        # 构建邮件内容
        subject = "博客网站注册验证码"
        content = f"""
        您好！
        
        您正在注册博客网站，验证码为：{code}
        
        验证码有效期为5分钟，请尽快完成注册。
        如非本人操作，请忽略此邮件。
        
        此邮件为系统自动发送，请勿回复。
        """
        
        message = MIMEText(content.strip(), 'plain', 'utf-8')
        message['From'] = EMAIL_CONFIG['send_by']
        message['To'] = to_email
        message['Subject'] = Header(subject, 'utf-8')
        
        # 连接SMTP服务器并发送
        smtp = smtplib.SMTP_SSL(EMAIL_CONFIG['mail_host'], EMAIL_CONFIG['port'])
        smtp.login(EMAIL_CONFIG['send_by'], EMAIL_CONFIG['mail_pass'])
        smtp.sendmail(EMAIL_CONFIG['send_by'], [to_email], message.as_string())
        smtp.quit()
        
        return True
    except Exception as e:
        print(f"发送邮件失败: {e}")
        return False

@app.route('/get_verification_code', methods=['POST'])
def get_verification_code():
    """获取邮箱验证码"""
    email = request.form.get('email')
    if not email:
        return jsonify({'success': False, 'message': '请输入邮箱'})
        
    # 生成6位随机验证码
    code = ''.join(random.choices('0123456789', k=6))
    print(f"生成的验证码: {code}")  # 调试用
    
    # 保存验证码到数据库
    verification = EmailVerificationCode(email=email, code=code)
    try:
        db.session.add(verification)
        db.session.commit()
        print(f"验证码已保存到数据库")  # 调试用
    except Exception as e:
        print(f"保存验证码失败: {e}")  # 调试用
        db.session.rollback()
        return jsonify({'success': False, 'message': '验证码生成失败'})
    
    # 发送验证码邮件
    try:
        send_verification_email(email, code)
        return jsonify({'success': True, 'message': '验证码已发送'})
    except Exception as e:
        print(f"发送验证码失败: {e}")  # 调试用
        return jsonify({'success': False, 'message': '验证码发送失败'})

@app.route('/verify_code', methods=['POST'])
def verify_code():
    """验证验证码"""
    email = request.form.get('email')
    code = request.form.get('code')
    
    if not email or not code:
        return jsonify({'success': False, 'message': '请填写完整信息'})
    
    # 查询最新的未使用验证码
    verification = EmailVerificationCode.query.filter_by(
        email=email,
        code=code,
        is_used=False
    ).order_by(EmailVerificationCode.created_at.desc()).first()
    
    if not verification:
        return jsonify({'success': False, 'message': '验证码无效'})
    
    # 检查验证码是否过期(5分钟)
    if (datetime.utcnow() - verification.created_at).total_seconds() > 300:
        return jsonify({'success': False, 'message': '验证码已过期'})
    
    # 标记验证码已使用
    verification.is_used = True
    db.session.commit()
    
    return jsonify({'success': True, 'message': '验证成功'})

@app.route('/register', methods=['GET', 'POST'])
def register():
    if request.method == 'POST':
        username = request.form.get('username')
        password = request.form.get('password')
        email = request.form.get('email')
        verification_code = request.form.get('verification_code')
        
        if not all([username, password, email, verification_code]):
            flash('请填写所有必填字段')
            return redirect(url_for('register'))
            
        # 验证验证码
        code_record = EmailVerificationCode.query.filter_by(
            email=email,
            code=verification_code,
            is_used=False
        ).order_by(EmailVerificationCode.created_at.desc()).first()
        
        if not code_record:
            flash('验证码无效')
            return redirect(url_for('register'))
            
        # 检查验证码是否过期(5分钟)
        if (datetime.utcnow() - code_record.created_at).total_seconds() > 300:
            flash('验证码已过期')
            return redirect(url_for('register'))
            
        # 标记验证码已使用
        code_record.is_used = True
        
        # 创建新用户
        user = User(username=username, email=email, name=username)
        user.set_password(password)
        
        try:
            db.session.add(user)
            db.session.commit()
            flash('注册成功！请登录。')
            return redirect(url_for('login'))
        except:
            db.session.rollback()
            flash('注册失败，请重试')
            return redirect(url_for('register'))
            
    return render_template('register.html')

# 添加博客相关路由
@app.route('/blog')
def blog():
    page = request.args.get('page', 1, type=int)
    posts = Post.query.order_by(Post.created_at.desc()).paginate(
        page=page, per_page=10, error_out=False)
    return render_template('blog.html', posts=posts)

@app.route('/blog/new', methods=['GET', 'POST'])
@login_required
def new_post():
    if request.method == 'POST':
        title = request.form['title']
        content = request.form['content']
        category = request.form['category']
        
        if not title or not content:
            flash('标题和内容不能为空')
            return redirect(url_for('new_post'))
            
        post = Post(title=title, content=content, 
                   category=category, author=current_user)
        post.on_changed_content()
        db.session.add(post)
        db.session.commit()
        flash('文章发布成功！')
        return redirect(url_for('blog'))
        
    return render_template('new_post.html')

# @app.route('/post/<int:post_id>')
# def post(post_id):
#     post = Post.query.get_or_404(post_id)
#     # 获取文章的评论
#     comments = Comment.query.filter_by(
#         post_id=post_id,
#         parent_id=None  # 只获取顶层评论
#     ).order_by(Comment.created_at.desc()).all()
    
#     return render_template('post.html', post=post, comments=comments, current_user=current_user)
@app.route('/post/<int:post_id>')
def post(post_id):
    post = Post.query.get_or_404(post_id)
    # 获取文章的评论
    comments = Comment.query.filter_by(
        post_id=post_id,
        parent_id=None  # 只获取顶层评论
    ).order_by(Comment.created_at.desc()).all()

    # 这里不需要显式传递 current_user，因为 Flask-Login 会自动处理
    return render_template('post.html', post=post, comments=comments)


# 添加电影列表页面路由
@app.route('/movies')
def movies():
    movies = Movie.query.order_by(Movie.year.desc()).all()
    return render_template('movies.html', movies=movies)

# 添加新电影的路由
@app.route('/movie/add', methods=['POST'])
@login_required
def add_movie():
    title = request.form.get('title')
    year = request.form.get('year')
    category = request.form.get('category', '')

    if not title or not year or len(year) != 4 or len(title) > 60:
        flash('输入无效')
        return redirect(url_for('movies'))

    # 爬取电影信息
    movie_info = crawl_movie_info(title)
    
    movie = Movie(
        title=title,
        year=year,
        category=category
    )
    
    if movie_info:
        movie.play_url = movie_info['play_url']
        movie.description = movie_info['description']
        movie.poster_url = movie_info['poster_url']
        movie.rating = movie_info['rating']
        movie.director = movie_info['director']
        movie.actors = movie_info['actors']
    
    db.session.add(movie)
    db.session.commit()
    flash('电影添加成功！')
    return redirect(url_for('movies'))

# 添加电影爬虫函数
def crawl_movie_info(movie_title):
    """爬取可可影视的电影信息"""
    try:
        # 构建搜索URL
        search_url = f"https://www.kekemov.com/search/{movie_title}"
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
        }
        
        response = requests.get(search_url, headers=headers)
        soup = BeautifulSoup(response.text, 'html.parser')
        
        # 获取第一个搜索结果
        movie_link = soup.find('div', class_='movie-item').find('a')['href']
        movie_page = requests.get(movie_link, headers=headers)
        movie_soup = BeautifulSoup(movie_page.text, 'html.parser')
        
        # 提取信息
        info = {
            'play_url': movie_link,
            'description': movie_soup.find('div', class_='movie-description').text.strip(),
            'poster_url': movie_soup.find('div', class_='movie-poster').find('img')['src'],
            'rating': float(movie_soup.find('div', class_='rating').text.strip()),
            'director': movie_soup.find('div', class_='director').text.strip(),
            'actors': movie_soup.find('div', class_='actors').text.strip()
        }
        
        return info
    except Exception as e:
        print(f"爬取电影信息失败: {e}")
        return None

# 添加编辑博客文章的路由
@app.route('/blog/edit/<int:post_id>', methods=['GET', 'POST'])
@login_required
def edit_post(post_id):
    post = Post.query.get_or_404(post_id)
    if post.author != current_user:
        flash('你没有权限编辑这篇文章')
        return redirect(url_for('post', post_id=post_id))
        
    if request.method == 'POST':
        title = request.form['title']
        content = request.form['content']
        category = request.form['category']
        
        if not title or not content:
            flash('标题和内容不能为空')
            return redirect(url_for('edit_post', post_id=post_id))
            
        post.title = title
        post.content = content
        post.category = category
        post.on_changed_content()
        db.session.commit()
        flash('文章更新成功！')
        return redirect(url_for('post', post_id=post_id))
        
    return render_template('edit_post.html', post=post)

# 添加删除博客文章的路由
@app.route('/blog/delete/<int:post_id>', methods=['POST'])
@login_required
def delete_post(post_id):
    post = Post.query.get_or_404(post_id)
    if post.author != current_user:
        flash('你没有权限删除这篇文章')
        return redirect(url_for('post', post_id=post_id))
        
    db.session.delete(post)
    db.session.commit()
    flash('文章已删除')
    return redirect(url_for('blog'))

# 添加音乐路由
@app.route('/music')
def music():
    page = request.args.get('page', 1, type=int)
    genre = request.args.get('genre')
    
    query = Music.query
    if genre:
        query = query.filter_by(genre=genre)
        
    musics = query.order_by(Music.created_at.desc()).paginate(
        page=page, per_page=12, error_out=False)
    return render_template('music.html', musics=musics)

@app.route('/music/add', methods=['GET', 'POST'])
@login_required
def add_music():
    if request.method == 'POST':
        title = request.form.get('title')
        artist = request.form.get('artist')
        url = request.form.get('url')
        genre = request.form.get('genre')
        
        if not title or not url:
            flash('标题和音乐链接不能为空')
            return redirect(url_for('add_music'))
            
        music = Music(
            title=title,
            artist=artist,
            url=url,
            genre=genre,
            user_id=current_user.id
        )
        db.session.add(music)
        db.session.commit()
        flash('音乐添加成功！')
        return redirect(url_for('music'))
        
    return render_template('add_music.html')

# 添加电影推荐路由
@app.route('/movie_recommendations')
def movie_recommendations():
    # 获取推荐电影列表
    recommended_movies = Movie.query.order_by(
        Movie.recommend_index.desc(),
        Movie.created_at.desc()
    ).limit(6).all()
    
    # 按类别获取电影
    action_movies = Movie.query.filter_by(category='动作').limit(6).all()
    comedy_movies = Movie.query.filter_by(category='喜剧').limit(6).all()
    drama_movies = Movie.query.filter_by(category='剧情').limit(6).all()
    
    return render_template(
        'movie_recommendations.html',
        recommended_movies=recommended_movies,
        action_movies=action_movies,
        comedy_movies=comedy_movies,
        drama_movies=drama_movies
    )

# 添加评论相关路由
@app.route('/api/comments', methods=['POST'])
@login_required
def add_comment():
    data = request.get_json()
    content = data.get('content')
    post_id = data.get('post_id')
    movie_id = data.get('movie_id')
    music_id = data.get('music_id')
    parent_id = data.get('parent_id')
    
    if not content:
        return jsonify({'success': False, 'message': '评论内容不能为空'})
        
    comment = Comment(
        content=content,
        user_id=current_user.id,
        post_id=post_id,
        movie_id=movie_id,
        music_id=music_id,
        parent_id=parent_id
    )
    
    db.session.add(comment)
    db.session.commit()
    
    return jsonify({
        'success': True,
        'message': '评论成功',
        'comment': comment.to_dict()
    })

@app.route('/api/comments/<int:id>', methods=['DELETE'])
@login_required
def delete_comment(id):
    comment = Comment.query.get_or_404(id)
    if comment.user_id != current_user.id:
        return jsonify({'success': False, 'message': '没有权限删除此评论'})
        
    db.session.delete(comment)
    db.session.commit()
    
    return jsonify({'success': True, 'message': '评论已删除'})

# 添加网易云音乐评论爬取功能
def get_netease_comments(music_id):
    try:
        url = f'http://music.163.com/api/v1/resource/comments/R_SO_4_{music_id}'
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
        }
        response = requests.get(url, headers=headers)
        data = response.json()
        
        comments = []
        if data['code'] == 200:
            for item in data['comments'][:10]:  # 获取前10条评论
                comment = {
                    'content': item['content'],
                    'username': item['user']['nickname'],
                    'time': datetime.fromtimestamp(item['time']/1000).strftime('%Y-%m-%d %H:%M:%S'),
                    'liked': item['likedCount']
                }
                comments.append(comment)
                
        return comments
    except Exception as e:
        print(f"获取网易云音乐评论失败: {e}")
        return []

# AI助手配置
client = OpenAI(
    api_key="sk-a5a612d41a5b4b969160c1666f08c264",
    base_url="https://api.deepseek.com"  # 使用 v1 endpoint
)

# 存储用户会话历史
chat_histories = {}

@retry(
    stop=stop_after_attempt(3),  # 最多重试3次
    wait=wait_exponential(multiplier=1, min=4, max=10)  # 指数退避重试
)
def call_ai_api(messages):
    try:
        response = client.chat.completions.create(
            model="deepseek-chat",
            messages=messages,
            stream=False,
            temperature=0.7,
            max_tokens=2000
        )
        return response
    except Exception as e:
        print(f"API调用错误: {str(e)}")
        raise

@app.route('/api/ai/chat', methods=['POST'])
@login_required
def ai_chat():
    data = request.get_json()
    message = data.get('message')
    user_id = current_user.id
    
    if not message:
        return jsonify({'success': False, 'message': '请输入内容'})
    
    try:
        # 获取或创建用户的聊天历史
        if user_id not in chat_histories:
            chat_histories[user_id] = []
        
        # 添加用户消息
        chat_histories[user_id].append({
            "role": "user",
            "content": message
        })
        
        # 准备消息历史
        messages = [
            {
                "role": "system", 
                "content": """你是一个友好的AI助手。
                请用Markdown格式回复,保持回答简洁明了。
                如果涉及代码,请用对应的代码块标记。
                如果是列表,请用有序或无序列表标记。
                重要内容可以用加粗或斜体标记。
                请始终使用中文回复。
                """
            }
        ]
        
        # 只保留最近的对话历史
        if len(chat_histories[user_id]) > 10:
            messages.extend(chat_histories[user_id][-10:])
        else:
            messages.extend(chat_histories[user_id])
        
        # 调用 API
        try:
            response = call_ai_api(messages)
            
            # 获取回复
            ai_message = response.choices[0].message.content
            
            # 添加AI回复到历史记录
            chat_histories[user_id].append({
                "role": "assistant",
                "content": ai_message
            })
            
            # 将 Markdown 转换为 HTML
            ai_message_html = markdown.markdown(
                ai_message,
                extensions=['extra', 'codehilite', 'tables', 'toc']
            )
            
            return jsonify({
                'success': True,
                'message': '请求成功',
                'response': ai_message_html
            })
        except Exception as e:
            print(f"API调用失败: {str(e)}")
            return jsonify({
                'success': False,
                'message': '抱歉,AI助手暂时无法回应,请稍后再试'
            })
            
    except Exception as e:
        print(f"处理请求失败: {str(e)}")
        return jsonify({
            'success': False, 
            'message': '系统错误,请稍后再试'
        })

@app.route('/movie/<int:movie_id>')
def movie(movie_id):
    movie = Movie.query.get_or_404(movie_id)
    # 获取电影的评论
    comments = Comment.query.filter_by(
        movie_id=movie_id,
        parent_id=None
    ).order_by(Comment.created_at.desc()).all()
    
    # 获取网易云音乐评论
    netease_comments = []
    if movie.netease_id:  # 如果设置了网易云音乐ID
        netease_comments = get_netease_comments(movie.netease_id)
    
    return render_template(
        'movie.html',
        movie=movie,
        comments=comments,
        netease_comments=netease_comments
    )

if __name__ == '__main__':
    init_db()
    app.run(debug=True)
